import Router from 'koa-router';
//用redis 发的验证码 对应的每个人  
import Redis from 'koa-redis'
// smtp服务  在node安装一个对应的程序  
import nodeMailer from 'nodemailer'
//数据库导进来
import User from '../dbs/models/users'
import Passport from './utils/passport'
import Email from '../dbs/config'
import axios from './utils/axios'

//定义一个前缀 /users
let router = new Router({ prefix: '/users' })

//获取redis客户端
let Store = new Redis().client
//一定要用post的方式  主要安全些
router.post('/signup', async (ctx) => {
  //结构赋值 来获取  要用ctx.request.body
  const { username, password, email, code } = ctx.request.body;
  //校验  把存在redis中的数据拿出来验证
  if (code) {
    //加个nodemail前缀 区分东西   用这个username来标识验证码
    //hget这个是hash值  加了个前缀 nodemail:${username}
    const saveCode = await Store.hget(`nodemail:${username}`, 'code')
    //还要获取过期时间
    const saveExpire = await Store.hget(`nodemail:${username}`, 'expire')
    if (code === saveCode) {
      if (new Date().getTime() - saveExpire > 0) {
        ctx.body = {
          code: -1,
          msg: '验证码已过期，请重新尝试'
        }
        return false
      }
      //验证码不相等
    } else {
      ctx.body = {
        code: -1,
        msg: '请填写正确的验证码'
      }
    }
    //就是redis没有获取验证码  直接返回出去
  } else {
    ctx.body = {
      code: -1,
      msg: '请填写验证码'
    }
  }
  let user = await User.find({ username })
  if (user.length) {
    ctx.body = {
      code: -1,
      msg: '已被注册'
    }
    return
  }
  //创建一个写库的动作
  let nuser = await User.create({ username, password, email })
  if (nuser) {
    let res = await axios.post('/users/signin', { username, password })
    if (res.data && res.data.code === 0) {
      ctx.body = {
        code: 0,
        msg: '注册成功',
        user: res.data.user
      }
      // 没有拿到
    } else {
      ctx.body = {
        code: -1,
        msg: 'error'
      }
    }
  } else {
    ctx.body = {
      code: -1,
      msg: '注册失败'
    }
  }
})

router.post('/signin', async (ctx, next) => {
  // 这个是possport验证策略   
  return Passport.authenticate('local', function (err, user, info, status) {
    if (err) {
      ctx.body = {
        code: -1,
        msg: err
      }
    } else {
      if (user) {
        ctx.body = {
          code: 0,
          msg: '登录成功',
          user
        }
        //做一个登入的动作
        return ctx.login(user)
      } else {
        ctx.body = {
          code: 1,
          //具体异常的信息打印出来info
          msg: info
        }
      }
    }
    //固定用法
  })(ctx, next)
})

router.post('/verify', async (ctx, next) => {
  let username = ctx.request.body.username
  const saveExpire = await Store.hget(`nodemail:${username}`, 'expire')
  if (saveExpire && new Date().getTime() - saveExpire < 0) {
    ctx.body = {
      code: -1,
      msg: '验证请求过于频繁，1分钟内1次'
    }
    return false
  }
  //这个是发送的对象
  let transporter = nodeMailer.createTransport({
    //这个是在possport中取出来的数据
    service: 'qq',
    auth: {
      user: Email.smtp.user,
      pass: Email.smtp.pass
    }
  })
  //这是发送的内容
  let ko = {
    code: Email.smtp.code(),
    expire: Email.smtp.expire(),
    //这是给谁发的
    email: ctx.request.body.email,
    //用的那个用户名  给谁
    user: ctx.request.body.username
  }
  //发送的内容
  let mailOptions = {
    //上面可以在对象
    from: `"认证邮件" <${Email.smtp.user}>`,
    to: ko.email,
    subject: '《慕课网高仿美团网全栈实战》注册码',
    html: `您在《慕课网高仿美团网全栈实战》课程中注册，您的邀请码是${ko.code}`
  }
  //发送email
  await transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
      return console.log(error)
    } else {
      //来存储信息  在上面可以来调用里面的值的    重点
      Store.hmset(`nodemail:${ko.user}`, 'code', ko.code, 'expire', ko.expire, 'email', ko.email)
    }
  })
  ctx.body = {
    code: 0,
    msg: '验证码已发送，可能会有延时，有效期1分钟'
  }
})

router.get('/exit', async (ctx, next) => {
  //执行一个退出来的动作
  await ctx.logout()
  //如果没有注销掉就要给返回-1
  if (!ctx.isAuthenticated()) {
    ctx.body = {
      code: 0
    }
  } else {
    ctx.body = {
      code: -1
    }
  }
})

router.get('/getUser', async (ctx) => {
  //其实这个就是登入状态
  if (ctx.isAuthenticated()) {
    const { username, email } = ctx.session.passport.user
    ctx.body = {
      user: username,
      email
    }
  } else {
    //没有登入的状态
    ctx.body = {
      user: '',
      email: ''
    }
  }
})

export default router
//写完这个还是需要在index.js中导入进去
